﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MagicArena.framework.state;
using MagicArena.framework.physics.util;
using MagicArena.framework.physics._2d;
using MagicArena.framework.toon;

namespace MagicArena.framework.physics._2d
{
    public abstract class ACollider2d : ACollider
    {
        public State Xpos
        {
            get;
            protected set;
        }
        public State Ypos
        {
            get;
            protected set;
        }
        public ACollider2d(State xpos, State ypos)
        {
            if (xpos.Id != State.Common.Xpos) throw new ArgumentException("xpos has invalid Id");
            if (ypos.Id != State.Common.Ypos) throw new ArgumentException("ypos has invalid Id");

            Xpos = xpos;
            Ypos = ypos;

            AddToPhysics();
        }
        public ACollider2d(float xpos, float ypos)
        {
            Xpos = new State(State.Common.Xpos, xpos);
            Ypos = new State(State.Common.Ypos, ypos);

            AddToPhysics();
        }
        ~ACollider2d()
        {
            RemoveFromPhysics();
        }

        protected virtual void AddToPhysics()
        {
            PhysicsEngine2d.Instance.AddCollider(this);
        }
        protected virtual void RemoveFromPhysics()
        {
            PhysicsEngine2d.Instance.RemoveCollider(this);
        }
    }

    class Collider2dRect : ACollider2d
    {
        public State Width
        {
            get;
            private set;
        }
        public State Height
        {
            get;
            private set;
        }
        public Rectangle Rect
        {
            get
            {
                return new Rectangle(Xpos.Value, Ypos.Value, Width.Value, Height.Value);
            }
        }

        /// <summary>
        /// Creates a new collider2d that uses the position state information of Toon if possible
        /// </summary>
        /// <param name="t">The toon which this collider2d should sync state info with</param>
        /// <param name="XPOS">default value if no corresponding state in Toon t</param>
        /// <param name="YPOS">default value if no corresponding state in Toon t</param>
        /// <param name="WIDTH">default value if no corresponding state in Toon t</param>
        /// <param name="HEIGHT">default value if no corresponding state in Toon t</param>
        public Collider2dRect(Toon t, float XPOS = 0, float YPOS = 0, float WIDTH = 10, float HEIGHT = 10)
            : base(State.FindState(t.States, State.Common.Xpos, XPOS), State.FindState(t.States, State.Common.Ypos, YPOS))
        {
            Width = State.FindState(t.States, State.Common.Width, WIDTH);
            Height = State.FindState(t.States, State.Common.Height, HEIGHT);
        }

        public Collider2dRect(State xpos, State ypos, State width, State height) : base(xpos, ypos)
        {
            if (width.Id != State.Common.Width) throw new ArgumentException("width has invalid Id");
            if (height.Id != State.Common.Height) throw new ArgumentException("height has invalid Id");

            Width = width;
            Height = height;
        }
        public Collider2dRect(float xpos, float ypos, float width, float height) 
            : base(xpos, ypos)
        {
            Width = new State(State.Common.Width, width);
            Height = new State(State.Common.Height, height);
        }
    }

    class Collider2dCircle : ACollider2d
    {
        public State Radius
        {
            get;
            private set;
        }
        public Circle Circle
        {
            get
            {
                return new Circle(this.Xpos.Value, this.Ypos.Value, this.Radius.Value);
            }
        }

        public Collider2dCircle(State xpos, State ypos, State radius)
            : base(xpos, ypos)
        {
            if (radius.Id != State.Common.Radius) throw new ArgumentException("radius has invalid Id");
            Radius = radius;
        }
    }
}
